<?php
/**
 * 
 *
 * $Id:  class_core.php 2013-9-2  下午2:24:50 zhangzw $
 */

define('IN_FAMOUS', true);

class famous_core
{
    var $db = null;

    var $mem = null;

    var $session = null;

    var $config = array();

    var $var = array();

    var $cachelist = array();

    var $init_setting = true;
    var $init_user = true;
    var $init_session = true;
    var $init_cron = true;
    var $init_misc = true;
    var $init_memory = true;

    var $initated = false;

    var $superglobal = array(
	        'GLOBALS' => 1,
	        '_GET' => 1,
	        '_POST' => 1,
	        '_REQUEST' => 1,
	        '_COOKIE' => 1,
	        '_SERVER' => 1,
	        '_ENV' => 1,
	        '_FILES' => 1,
        );

    /**
     * 允许记录最后一次访问的action的应用和模块
     * @var array
     */
    var $isLastView = array();
    var $lastAction = null;

    /**
     * 单例模式
     *
     * <code>
     * $famous = & famous_core::instance();
     * </code>
     *
     * return famous_core
     */
    static function &instance()
    {
        static $object;

        if (empty($object)) {
            $object = new famous_core();
        }

        return $object;
    }

    /**
     * 构造函数
     * 初始化环境
     * 初始化配置
     * 初始化输入
     */
    function famous_core()
    {
        $this->_init_env();
        $this->_init_config();
        $this->_init_input();
        $this->_init_output();
    }

    function init($init_steps = array())
    {
        if (!$this->initated) {
            if (empty($init_steps)) {
                $this->_init_memory();
                $this->_init_user();
                $this->_init_last_view();
            } else {
                foreach ($init_steps as $step) {
                    $this->$step();
                }
            }

            $this->_init_session();
            // $this->_init_setting();
            // $this->_init_cron();
            // $this->_init_misc();
            // $this->_init_db();
        }
        $this->initated = true;
    }

    /**
     * 初始化访问记录
     */
    function _init_last_view()
    {
        global $_G;        

        if (empty($_G['action'])) {
            $_G['action'] = empty($this->lastAction) ? 'index' : $this->lastAction;            
        }
       
    }

    /**
     * 初始化环境
     */
    function _init_env()
    {
        if (phpversion() < '5.3.0') {
            set_magic_quotes_runtime(0);
        }
       
        define('FAMOUS_ROOT', substr(dirname(__file__), 0, -12));        
        define('MAGIC_QUOTES_GPC', function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc());
        define('ICONV_ENABLE', function_exists('iconv'));
        define('MB_ENABLE', function_exists('mb_convert_encoding'));
        define('EXT_OBGZIP', function_exists('ob_gzhandler'));
        
        define('ENVIRONMENT', 'development');
        if (defined('ENVIRONMENT')) {
            switch (ENVIRONMENT) {
                case 'development':
                    error_reporting(E_ALL);
                    break;

                case 'testing':
                case 'production':
                    error_reporting(0);
                    break;

                default:
                    exit('The application ENVIRONMENT is not set correctly.');
            }
        }
        
        

        define('TIMESTAMP', time());
        $this->timezone_set();

        if (!defined('FAMOUS_CORE_FUNCTION') && !@include (FAMOUS_ROOT . './source/function/function_core.php')) {
            exit('function_core.php is missing');
        }
       
        if (function_exists('ini_get')) {
            $memorylimit = @ini_get('memory_limit');
            if ($memorylimit && return_bytes($memorylimit) < 33554432 && function_exists('ini_set')) {
                ini_set('memory_limit', '128m');
            }
        }

        define('IS_ROBOT', false);

        foreach ($GLOBALS as $key => $value) {
            if (!isset($this->superglobal[$key])) {
                $GLOBALS[$key] = null;
                unset($GLOBALS[$key]);
            }
        }

        global $_G;
        $_G = array(
            'uid' => 0,
            'username' => '',
            'short_username' => '',
            'adminid' => 0,
            'groupid' => 1,
            'verify' => 0,
            'sid' => '',
            'formhash' => '',
            'timestamp' => TIMESTAMP,
            'starttime' => dmicrotime(),
            'clientip' => $this->_get_client_ip(),
            'referer' => '',
            'charset' => '',
            'gzipcompress' => '',
            'authkey' => '',
            'timenow' => array(),
            'PHP_SELF' => '',
            'siteurl' => '',
            'siteroot' => '',
            'config' => array(),
            'setting' => array(),
            'member' => array(),
            'group' => array(),
            'cookie' => array(),
            'style' => array('styleid' => 2, 'tpldir' => './template/spring'),
            'cache' => array(),
            'session' => array(),
            'lang' => array(),
            'my_app' => array(),
            'my_userapp' => array(),
            'forum' => array(),
            );
        $_G['PHP_SELF'] = htmlspecialchars($_SERVER['SCRIPT_NAME'] ? $_SERVER['SCRIPT_NAME'] : $_SERVER['PHP_SELF']);
        $_G['basescript'] = CURSCRIPT;        
        $_G['basefilename'] = basename($_G['PHP_SELF']);
        // $_G['siteurl'] = htmlspecialchars('http://'.$_SERVER['HTTP_HOST'].preg_replace("/\/+(api)?\/*$/i", '', substr($_G['PHP_SELF'], 0, strrpos($_G['PHP_SELF'], '/'))).'/');
        $_G['siteroot'] = substr($_G['PHP_SELF'], 0, -strlen($_G['basefilename']));
        
        $this->var = &$_G;

    }

    /**
     * 初始化数据链接
     */
    function _init_db()
    {
        $this->db = &DB::object();
        $this->db->set_config($this->config['db']);
        $this->db->connect();
    }

    /**
     * 初始化用户信息，通过cookie来获取数据
     */
    function _init_user()
    {
        
    }

    /**
     * 初始化SESSION
     */
    function _init_session()
    {
    	$this->session = new famous_session_db();
    	$this->session->excute();
    	
    	// 开启session
    	session_start();
    }

    /**
     * 初始化配置
     */
    function _init_config()
    {
        $_config = array();

        $config_path = FAMOUS_ROOT . './config/' . ENVIRONMENT . '/config_global.php';
		
        if(file_exists($config_path)){
            @include $config_path;
        } else {
            @include FAMOUS_ROOT . './config/config_global.php';
        }

        if (empty($_config)) {
            //system_error('config_notfound');
        }

        // 自定义配置文件
        if (CURCONFIG) {
            $config_path = FAMOUS_ROOT . './config/' . ENVIRONMENT . '/config_' . CURSCRIPT . '.php';
            if(file_exists($config_path)){
                @include $config_path;
            } else {
                @include FAMOUS_ROOT . './config/config_' . CURSCRIPT . '.php';
            }
        }

        if (empty($_config['security']['authkey'])) {
            $_config['security']['authkey'] = md5($_config['cookie']['cookiepre'] . $_config['db'][1]['dbname']);
        }

        define('STATICURL', !empty($_config['output']['staticurl']) ? $_config['output']['staticurl'] : 'static/');
        $this->var['staticurl'] = STATICURL;
        define('DATAURL', !empty($_config['output']['dataurl']) ? $_config['output']['dataurl'] : '/data/');
        $this->var['dataurl'] = DATAURL;
        define('ATTACHDIR', !empty($_config['setting']['attachdir']) ? $_config['setting']['attachdir'] : '/data/');
        define('VERSION', $_config['setting']['version']);
        $this->var['version'] = VERSION;
        define('RELEASE', $_config['setting']['release']);
        $this->var['release'] = RELEASE;

        $this->config = &$_config;
        $this->var['config'] = &$_config;

        if (substr($_config['cookie']['cookiepath'], 0, 1) != '/') {
            $this->var['config']['cookie']['cookiepath'] = '/' . $this->var['config']['cookie']['cookiepath'];
        } 
        define('SITEURL', !empty($_config['setting']['siteurl']) ? "http://{$_SERVER['HTTP_HOST']}/" : '/');
        $this->var['siteurl'] = $this->var['config']['setting']['siteurl'];
        $this->var['config']['cookie']['cookiepre'] = $this->var['config']['cookie']['cookiepre'] . substr(md5($this->var['config']['cookie']['cookiepath'] . '|' . $this->var['config']['cookie']['cookiedomain']), 0, 4) . '_';
        // 取消 $_SERVER['HTTP_USER_AGENT'] ie8 有兼容视图BUG
        // $this->var['authkey'] = md5($_config['security']['authkey'] . $_SERVER['HTTP_USER_AGENT']);
        $this->var['authkey'] = md5(md5($_config['security']['authkey']) . md5($this->var['config']['db']['1']['dbpw'] . $this->var['config']['db'][1]['dbname']));
        $this->timezone_set($this->var['config']['setting']['timezone']);
        
    }

    /**
     * 初始化输入
     */
    function _init_input()
    {
        if (isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])) {
            exit('request_tainting');
        }
        
		// 重写规则
        if (!empty($_GET['rewrite'])) {
            $query_string = '?mod=';
            $param = explode('-', $_GET['rewrite']);
            $query_string .= $_GET['mod'] = $param[0];
            array_shift($param);
            $paramc = count($param);
            for ($i = 0; $i < $paramc; $i += 2) {
                $_REQUEST[$param[$i]] = $_GET[$param[$i]] = $param[$i + 1];
                $query_string .= '&' . $param[$i] . '=' . $param[$i + 1];
            }
            $_SERVER['QUERY_STRING'] = $query_string;
            unset($param, $paramc, $query_string);
        }

        if (!MAGIC_QUOTES_GPC) {
            $_GET = daddslashes($_GET);
            $_POST = daddslashes($_POST);
            $_COOKIE = daddslashes($_COOKIE);
            //$_FILES = daddslashes($_FILES);
        }

        $prelength = strlen($this->config['cookie']['cookiepre']);
        foreach ($_COOKIE as $key => $val) {
            if (substr($key, 0, $prelength) == $this->config['cookie']['cookiepre']) {
                $this->var['cookie'][substr($key, $prelength)] = $val;
            }
        }        

        $_GET['diy'] = empty($_GET['diy']) ? '' : $_GET['diy'];

        foreach (array_merge($_POST, $_GET) as $k => $v) {
            $this->var['gp_' . $k] = $v;
        }

        $this->var['mod'] = empty($this->var['gp_mod']) ? '' : htmlspecialchars($this->var['gp_mod']);
        $this->var['action'] = empty($this->var['gp_action']) ? '' : htmlspecialchars($this->var['gp_action']);
        $this->var['inajax'] = empty($this->var['gp_inajax']) ? 0 : (empty($this->var['config']['output']['ajaxvalidate']) ? 1 : ($_SERVER['REQUEST_METHOD'] == 'GET' && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' || $_SERVER['REQUEST_METHOD'] == 'POST' ? 1 : 0));
        $this->var['page'] = empty($this->var['gp_page']) ? 1 : max(1, intval($this->var['gp_page']));
        $this->var['sid'] = $this->var['cookie']['sid'] = isset($this->var['cookie']['sid']) ? htmlspecialchars($this->var['cookie']['sid']) : '';


        // url传递来源页地址
        $this->var['referer'] = '';
        if (isset($this->var['gp_referer']) && $this->var['gp_referer']) {
            // 检查域名的合法性
            $parse = parse_url($this->var['gp_referer']);
            if (!isset($parse['host']) || $parse['host'] == $_SERVER['HTTP_HOST']) {
                $this->var['referer'] = strip_tags($this->var['gp_referer']);
            }
        }
    }

    /**
     * 初始化输出
     */
    function _init_output()
    {
        if ($this->config['security']['urlxssdefend'] && isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'GET' && !empty($_SERVER['REQUEST_URI'])) {
            $temp = urldecode($_SERVER['REQUEST_URI']);
            if (strpos($temp, '<') !== false) {
                // system_error('request_tainting');
                exit('request_tainting');
            }
        }

        if ($this->config['security']['attackevasive'] && (!defined('CURSCRIPT') || !in_array($this->var['mod'], array( 'seccode', 'secqaa','swfupload')))) {
            if (is_string($this->config['security']['attackevasive'])) {
                $attackevasive_tmp = explode('|', $this->config['security']['attackevasive']);
                $attackevasive = 0;
                foreach ($attackevasive_tmp as $key => $value) {
                    $attackevasive += intval($value);
                }
                unset($attackevasive_tmp);
            } else {
                $attackevasive = $this->config['security']['attackevasive'];
            }
            // require_once libfile('misc/security', 'include');
        }

        $allowgzip = $this->config['output']['gzip'] && empty($this->var['inajax']) && $this->var['mod'] != 'attachment' && EXT_OBGZIP;
        setglobal('gzipcompress', $allowgzip);
        ob_start($allowgzip ? 'ob_gzhandler' : null);

        setglobal('charset', $this->config['output']['charset']);
        define('CHARSET', $this->config['output']['charset']);        
        if ($this->config['output']['forceheader']) {
            @header('Content-Type: text/html; charset=' . CHARSET);
        }
    }

    /**
     * 初始化设置
     */
    function _init_setting()
    {
        if ($this->init_setting) {
            if (empty($this->var['setting'])) {
                $this->cachelist[] = 'setting';
            }

            if (empty($this->var['style'])) {
                $this->cachelist[] = 'style_default';
            }

            if (!isset($this->var['cache']['cronnextrun'])) {
                $this->cachelist[] = 'cronnextrun';
            }
        }

        if (!is_array($this->var['setting'])) {
            $this->var['setting'] = array();
        }
        
    }

    /**
     * 初始化风格
     */
    function _init_style()
    {        
        if (is_array($this->var['style'])) {
            foreach ($this->var['style'] as $key => $val) {
                $key = strtoupper($key);
                if (!defined($key) && !is_array($val)) {
                    define($key, $val);
                }
            }
        }
    }

    /**
     * 取出用户IP地址
     */
    function _get_client_ip()
    {
        $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
        if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } else
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) and preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
                foreach ($matches[0] as $xip) {
                    if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
                        $ip = $xip;
                        break;
                    }
                }
            }

        return $ip;
    }

    /**
     * 初始化 缓存
     */
    function _init_memory()
    {    
    	
        $this->mem = new famous_memory();
        if ($this->init_memory) {
            $this->mem->init($this->config['memory']);
        }
        $this->var['memory'] = $this->mem->type;
    }

    /**
     * 设置时区
     */
    function timezone_set($timeoffset = 0)
    {
        if (function_exists('date_default_timezone_set')) {
            @date_default_timezone_set('Etc/GMT' . ($timeoffset > 0 ? '-' : '+') . (abs($timeoffset)));
        }
    }
}

class db_mysql
{
    var $tablepre;
    var $version = '';
    var $querynum = 0;
    var $curlink;
    var $begin = false; // 事务开始状态
    var $link = array();
    var $config = array();
    var $sqldebug = array();
    var $map = array();
    var $serverid = 1;

    function db_mysql($config = array())
    {
        if (!empty($config)) {
            $this->set_config($config);
        }
    }

    function set_config($config)
    {
        $this->config = &$config;
        $this->tablepre = $config['1']['tablepre'];
        if (!empty($this->config['map'])) {
            $this->map = $this->config['map'];
        }
    }

    function connect($serverid = 1, $istask = 0)
    {

        if (empty($this->config) || empty($this->config[$serverid])) {
            $this->halt('config_db_not_found');
        }

        $this->link[$serverid] = $this->_dbconnect($this->config[$serverid]['dbhost'], $this->config[$serverid]['dbuser'], $this->config[$serverid]['dbpw'], $this->config[$serverid]['dbcharset'], $this->config[$serverid]['dbname'], $this->config[$serverid]['pconnect'], $istask);
        $this->curlink = $this->link[$serverid];
        $this->serverid = $serverid;
        return $this->curlink;
    }

    function _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect, $istask = 0)
    {
        $link = null;
        $func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';
        if (!$link = @$func($dbhost, $dbuser, $dbpw, 1)) {
            if ($istask)
                return false;
            $this->halt('notconnect');
        } else {
            $this->curlink = $link;
            if ($this->version() > '4.1') {
                $dbcharset = $dbcharset ? $dbcharset : $this->config[1]['dbcharset'];
                $serverset = $dbcharset ? 'character_set_connection=' . $dbcharset . ', character_set_results=' . $dbcharset . ', character_set_client=binary' : '';
                $serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',') . 'sql_mode=\'\'') : '';
                $serverset && mysql_query("SET $serverset", $link);
            }
            $dbname && @mysql_select_db($dbname, $link);
        }
        return $link;
    }

    function table_name($tablename)
    {
        if (!empty($this->map) && !empty($this->map[$tablename])) {
            $id = $this->map[$tablename];
            if (!$this->link[$id]) {
                $this->connect($id);
            }
            $this->curlink = $this->link[$id];
        } else {
            $this->curlink = $this->link[1];
        }
        return $this->tablepre . $tablename;
    }

    function select_db($dbname)
    {
        return mysql_select_db($dbname, $this->curlink);
    }

    function delete($table, $condition, $limit = 0, $unbuffered = true)
    {
        if (empty($condition)) {
            $where = '1';
        } elseif (is_array($condition)) {
            $where = DB::implode_field_value($condition, ' AND ');
        } else {
            $where = $condition;
        }
        $sql = "DELETE FROM " . DB::table($table) . " WHERE $where " . ($limit ? "LIMIT $limit" : '');
        return $this->query($sql, ($unbuffered ? 'UNBUFFERED' : ''));
    }

    function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false)
    {

        $sql = DB::implode_field_value($data);

        $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';

        $table = DB::table($table);
        $silent = $silent ? 'SILENT' : '';

        $return = $this->query("$cmd $table SET $sql", $silent);

        return $return_insert_id ? $this->insert_id() : $return;

    }

    function update($table, $data, $condition, $unbuffered = false, $low_priority = false)
    {
        $sql = DB::implode_field_value($data);
        $cmd = "UPDATE " . ($low_priority ? 'LOW_PRIORITY' : '');
        $table = DB::table($table);
        $where = '';
        if (empty($condition)) {
            $where = '1';
        } elseif (is_array($condition)) {
            $where = DB::implode_field_value($condition, ' AND ');
        } else {
            $where = $condition;
        }
        $res = $this->query("$cmd $table SET $sql WHERE $where", $unbuffered ? 'UNBUFFERED' : '');
        return $res;
    }

    function fetch_array($query, $result_type = MYSQL_ASSOC)
    {
        return mysql_fetch_array($query, $result_type);
    }

    function fetch_first($sql)
    {
        return $this->fetch_array($this->query($sql));
    }

    function result_first($sql)
    {
        return $this->result($this->query($sql), 0);
    }

    function query($sql, $type = '')
    {

        if (ENVIRONMENT != 'production') {
            $starttime = dmicrotime();
        }
        $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ? 'mysql_unbuffered_query' : 'mysql_query';
        if (!($query = $func($sql, $this->curlink))) {
            if (in_array($this->errno(), array(2006, 2013)) && substr($type, 0, 5) != 'RETRY') {
                $this->connect($this->serverid);
                return $this->query($sql, 'RETRY' . $type);
            }
            // 发生错误时事务回滚
            if ($this->begin) {
                $this->rollback();
            }
            if ($type != 'SILENT' && substr($type, 5) != 'SILENT') {
                $this->halt('query_error', $sql);
            }
        }

        if (ENVIRONMENT != 'production') {
            $this->sqldebug[] = array(
                $sql,
                number_format((dmicrotime() - $starttime), 6),
                debug_backtrace());
            if (isset($this->config[$this->serverid]['log']) && $this->config[$this->serverid]['log']) {
                $logfile = FAMOUS_ROOT . 'data/log/sql/' . date('Y-m-d') . '.php';
                dmkdir($logfile);
                $fp = fopen($logfile, 'a+');
                fwrite($fp, '<?php exit; ?>' . $sql . "\n");
                fclose($fp);
                @chmod($logfile, 0666);
            }
        }

        $this->querynum++;
        return $query;
    }

    function affected_rows()
    {
        return mysql_affected_rows($this->curlink);
    }

    function error()
    {
        return (($this->curlink) ? mysql_error($this->curlink) : mysql_error());
    }

    function errno()
    {
        return intval(($this->curlink) ? mysql_errno($this->curlink) : mysql_errno());
    }

    function result($query, $row = 0)
    {
        $query = @mysql_result($query, $row);
        return $query;
    }

    function num_rows($query)
    {
        $query = mysql_num_rows($query);
        return $query;
    }

    function num_fields($query)
    {
        return mysql_num_fields($query);
    }

    function free_result($query)
    {
        return mysql_free_result($query);
    }

    function insert_id()
    {
        return ($id = mysql_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
    }

    function fetch_row($query)
    {
        $query = mysql_fetch_row($query);
        return $query;
    }

    function fetch_fields($query)
    {
        return mysql_fetch_field($query);
    }

    /**
     * 事务开启
     */
    function begin()
    {
        $this->query("SET autocommit=0"); // 禁止自动提交
        $this->query("BEGIN"); // 开始一个事务
        $this->begin = true;
    }

    /**
     * 事务回滚
     */
    function rollback()
    {
        $this->query("ROLLBACK");
    }

    /**
     * 事务提交
     */
    function commit()
    {
        $this->query("COMMIT");
    }

    function version()
    {
        if (empty($this->version)) {
            $this->version = mysql_get_server_info($this->curlink);
        }
        return $this->version;
    }

    function close()
    {
        return mysql_close($this->curlink);
    }

    function halt($message = '', $sql = '')
    {
        require_once libfile('class/error');
        // weibo_error::db_error($message, $sql . ' ----- ' . mysql_error($this->curlink));
    }

}

class DB
{

    function table($table)
    {
        return DB::_execute('table_name', $table);
    }

    function delete($table, $condition, $limit = 0, $unbuffered = true)
    {
        if (empty($condition)) {
            $where = '1';
        } elseif (is_array($condition)) {
            $where = DB::implode_field_value($condition, ' AND ');
        } else {
            $where = $condition;
        }
        $sql = "DELETE FROM " . DB::table($table) . " WHERE $where " . ($limit ? "LIMIT $limit" : '');
        return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));
    }

    function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false)
    {

        $sql = DB::implode_field_value($data);

        $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';

        $table = DB::table($table);
        $silent = $silent ? 'SILENT' : '';

        $return = DB::query("$cmd $table SET $sql", $silent);

        return $return_insert_id ? DB::insert_id() : $return;

    }

    function update($table, $data, $condition, $unbuffered = false, $low_priority = false)
    {
        $sql = DB::implode_field_value($data);
        $cmd = "UPDATE " . ($low_priority ? 'LOW_PRIORITY' : '');
        $table = DB::table($table);
        $where = '';
        if (empty($condition)) {
            $where = '1';
        } elseif (is_array($condition)) {
            $where = DB::implode_field_value($condition, ' AND ');
        } else {
            $where = $condition;
        }
        $res = DB::query("$cmd $table SET $sql WHERE $where", $unbuffered ? 'UNBUFFERED' : '');
        return $res;
    }

    function implode_field_value($array, $glue = ',')
    {
        $sql = $comma = '';
        foreach ($array as $k => $v) {
            $sql .= $comma . "`$k`='" . addslashes($v) . "'";
            $comma = $glue;
        }
        return $sql;
    }

    function insert_id()
    {
        return DB::_execute('insert_id');
    }

    function fetch($resourceid, $type = MYSQL_ASSOC)
    {
        return DB::_execute('fetch_array', $resourceid, $type);
    }

    function fetch_first($sql)
    {
        DB::checkquery($sql);
        return DB::_execute('fetch_first', $sql);
    }

    function result($resourceid, $row = 0)
    {
        return DB::_execute('result', $resourceid, $row);
    }

    function result_first($sql)
    {
        DB::checkquery($sql);
        return DB::_execute('result_first', $sql);
    }

    function query($sql, $type = '')
    {
        DB::checkquery($sql);
        return DB::_execute('query', $sql, $type);
    }

    function num_rows($resourceid)
    {
        return DB::_execute('num_rows', $resourceid);
    }

    function affected_rows()
    {
        return DB::_execute('affected_rows');
    }

    function free_result($query)
    {
        return DB::_execute('free_result', $query);
    }

    function begin()
    {
        return DB::_execute('begin');
    }

    function commit()
    {
        return DB::_execute('commit');
    }

    function close()
    {
        return DB::_execute('close');
    }

    function error()
    {
        return DB::_execute('error');
    }

    function errno()
    {
        return DB::_execute('errno');
    }

    function _execute($cmd, $arg1 = '', $arg2 = '')
    {
        static $db;
        if (empty($db))
            $db = &DB::object();
        $res = $db->$cmd($arg1, $arg2);
        return $res;
    }

    function &object()
    {
        static $db;

        if (empty($db)) {
            $db = new db_mysql();
            $db->set_config(getglobal('config/db'));
            $db->connect();
        }

        return $db;
    }

    function checkquery($sql)
    {
        static $status = null, $checkcmd = array('SELECT','UPDATE','INSERT','REPLACE','DELETE');
        if ($status === null)
            $status = getglobal('config/security/querysafe/status');
        if ($status) {
            $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
            if (in_array($cmd, $checkcmd)) {
                $test = DB::_do_query_safe($sql);
                if ($test < 1)
                    DB::_execute('halt', 'security_error', $sql);
            }
        }
        return true;
    }

    function _do_query_safe($sql)
    {
        static $_CONFIG = null;
        if ($_CONFIG === null) {
            $_CONFIG = getglobal('config/security/querysafe');
        }

        $sql = str_replace(array(
            '\\\\',
            '\\\'',
            '\\"',
            '\'\''), '', $sql);
        $mark = $clean = '';
        if (strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false) {
            $clean = preg_replace("/'(.+?)'/s", '', $sql);
        } else {
            $len = strlen($sql);
            $mark = $clean = '';
            for ($i = 0; $i < $len; $i++) {
                $str = $sql[$i];
                switch ($str) {
                    case '\'':
                        if (!$mark) {
                            $mark = '\'';
                            $clean .= $str;
                        } elseif ($mark == '\'') {
                            $mark = '';
                        }
                        break;
                    case '/':
                        if (empty($mark) && $sql[$i + 1] == '*') {
                            $mark = '/*';
                            $clean .= $mark;
                            $i++;
                        } elseif ($mark == '/*' && $sql[$i - 1] == '*') {
                            $mark = '';
                            $clean .= '*';
                        }
                        break;
                    case '#':
                        if (empty($mark)) {
                            $mark = $str;
                            $clean .= $str;
                        }
                        break;
                    case "\n":
                        if ($mark == '#' || $mark == '--') {
                            $mark = '';
                        }
                        break;
                    case '-':
                        if (empty($mark) && substr($sql, $i, 3) == '-- ') {
                            $mark = '-- ';
                            $clean .= $mark;
                        }
                        break;

                    default:

                        break;
                }
                $clean .= $mark ? '' : $str;
            }
        }

        $clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($clean));

        if ($_CONFIG['afullnote']) {
            $clean = str_replace('/**/', '', $clean);
        }

        if (is_array($_CONFIG['dfunction'])) {
            foreach ($_CONFIG['dfunction'] as $fun) {
                if (strpos($clean, $fun . '(') !== false)
                    return '-1';
            }
        }

        if (is_array($_CONFIG['daction'])) {
            foreach ($_CONFIG['daction'] as $action) {
                if (strpos($clean, $action) !== false)
                    return '-3';
            }
        }

        if ($_CONFIG['dlikehex'] && strpos($clean, 'like0x')) {
            return '-2';
        }

        if (is_array($_CONFIG['dnote'])) {
            foreach ($_CONFIG['dnote'] as $note) {
                if (strpos($clean, $note) !== false)
                    return '-4';
            }
        }

        return 1;

    }

}

/**
 * SESSION 处理类
 * @author Administrator
 *
 */
class famous_session_db
{
	
	/**
	 * Session有效时间
	 */
	protected $lifeTime      = '';
	
	/**
	 * session保存的数据库名
	 */
	protected $sessionTable  = '';
	
	/**
	 * 数据库句柄
	 */
	protected $hander  = array();
	
	
	public function __construct(){
		global $_G;
		
		ini_set('session.auto_start', 0);
		ini_set('session.use_cookies', 1);
		ini_set('session.use_trans_sid', 1);
		ini_set('session.cookie_domain', $_G['config']['cookie']['cookiedomain']);
		ini_set('session.gc_maxlifetime', $_G['config']['session']['gcmaxlifetime']);
		
		$this->lifeTime = $_G['config']['session']['expire'];
		$this->sessionTable = DB::table('common_session');
		
	}
	
	/**
	 * 打开Session
	 * @access public
	 * @param string $savePath
	 * @param mixed $sessName
	 */
	public function open($savePath, $sessName){
		global $_G;
		
		$dbconfig = $_G['config']['db'][1];
		$hander = mysql_connect($dbconfig['dbhost'], $dbconfig['dbuser'],  $dbconfig['dbpw']);
		$dbSel = mysql_select_db($dbconfig['dbname']);
		if(!$hander || !$dbSel){
			return false;
		}
		$this->hander = $hander;
		return true;
	}
	
	/**
	 * 关闭Session
	 * @access public
	 */
	public function close(){
		$this->gc($this->lifeTime);
		return mysql_close($this->hander);
	}
	
	/**
	 * 读取Session
	 * @access public
	 * @param string $sessID
	 */
	public function read($sessID){
		$hander = $this->hander;
		$res = mysql_query("SELECT session_data AS data FROM ".$this->sessionTable." WHERE session_id = '$sessID'   AND session_expire >".time(),$hander);
		if($res) {
			$row = mysql_fetch_assoc($res);
			return $row['data'];
		}
		return "";
	}
	
	/**
	 * 写入Session
	 * @access public
	 * @param string $sessID
	 * @param String $sessData
	 */
	public function write($sessID,$sessData){
		$hander = $this->hander;
		$expire = time() + $this->lifeTime;
		mysql_query("REPLACE INTO  ".$this->sessionTable." (  session_id, session_expire, session_data)  VALUES( '$sessID', '$expire',  '$sessData')",$hander);
		if(mysql_affected_rows($hander))
			return true;
		return false;
	}
	
	/**
	 * 删除Session
	 * @access public
	 * @param string $sessID
	 */
	public function destroy($sessID){
		$hander = $this->hander;
		mysql_query("DELETE FROM ".$this->sessionTable." WHERE session_id = '$sessID'",$hander);
		if(mysql_affected_rows($hander))
			return true;
		return false;
	}
	
	/**
	 * Session 垃圾回收
	 * @access public
	 * @param string $sessMaxLifeTime
	 */
	public function gc($sessMaxLifeTime){		
		mysql_query("DELETE FROM ".$this->sessionTable." WHERE session_expire < ".time(),$this->hander);
		return mysql_affected_rows($this->hander);
	}
	
	
	// SESSION处理句柄
	public function excute(){		
		session_set_save_handler(array(&$this,"open"),
			array(&$this,"close"),
			array(&$this,"read"),
			array(&$this,"write"),
			array(&$this,"destroy"),
			array(&$this,"gc"));
	}
}


/**
 * 缓存处理类
 * @author zhangzw
 *
 */
class famous_memory
{
	var $config;
	var $extension = array();
	var $memory;
	var $prefix;
	var $type;
	var $keys;
	var $enable = false;

	function famous_memory()
	{
		$this->extension['eaccelerator'] = function_exists('eaccelerator_get');
		$this->extension['xcache'] = function_exists('xcache_get');
		$this->extension['memcache'] = extension_loaded('memcache');
	}

	function init($config)
	{
		$this->config = $config;
		$this->prefix = empty($config['prefix']) ? substr(md5($_SERVER['HTTP_HOST']), 0, 6) . '_' : $config['prefix'];
		$this->keys = array();

		if ($this->extension['memcache'] && !empty($config['memcache']['server'])) {
			require_once libfile('class/memcache');
			$this->memory = new famous_memcache();
			$this->memory->init($this->config['memcache']);
			if (!$this->memory->enable) {
				$this->memory = null;
			}
		}

		

		if (is_object($this->memory)) {
			$this->enable = true;
			$this->type = str_replace('weibo_', '', get_class($this->memory));
			$this->keys = $this->get('memory_system_keys');
			$this->keys = !is_array($this->keys) ? array() : $this->keys;
		}

	}

	function get($key)
	{
		$ret = null;

		if ($this->enable) {
			$ret = $this->memory->get($this->_key($key));
			if (!is_array($ret)) {
				$ret = null;
				if (array_key_exists($key, $this->keys)) {
					unset($this->keys[$key]);
					// $this->memory->set($this->_key('memory_system_keys'), array($this->keys));
				}
			} else {
				return $ret[0];
			}
		}

		return $ret;
	}

	function set($key, $value, $ttl = 0)
	{
		$ret = null;

		if ($this->enable) {
			$ret = $this->memory->set($this->_key($key), array($value), $ttl);
			if ($ret) {
				$this->keys[$key] = true;
				// $this->memory->set($this->_key('memory_system_keys'), array($this->keys));
			}
		}

		return $ret;
	}

	function rm($key)
	{
		$ret = null;

		if ($this->enable) {
			$ret = $this->memory->rm($this->_key($key));
			unset($this->keys[$key]);
			// $this->memory->set($this->_key('memory_system_keys'), array($this->keys));
		}

		return $ret;
	}

	function clear()
	{
		if ($this->enable && is_array($this->keys)) {
			$this->keys['memory_system_keys'] = true;
			foreach ($this->keys as $k => $v) {
				$this->memory->rm($this->_key($k));
			}
		}
		$this->keys = array();

		return true;
	}

	function _key($str)
	{
		return ($this->prefix) . $str;
	}
}


